package com.itheima.service.db.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itheima.domain.db.AnalysisByDay;
import com.itheima.domain.vo.AnalysisSummaryVo;
import com.itheima.domain.vo.AnalysisTimeVo;
import com.itheima.domain.vo.DistributionVo;
import com.itheima.domain.vo.YearsVo;
import com.itheima.mapper.AnalysisByDayMapper;
import com.itheima.mapper.LogMapper;
import com.itheima.service.db.AnalysisByDayService;
import com.itheima.util.ComputeUtil;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Service;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service //dubbo
public class AnalysisByDayServiceImpl implements AnalysisByDayService {


    @Autowired
    LogMapper logMapper;

    @Autowired
    AnalysisByDayMapper analysisByDayMapper;

    // 实战
    @Override
    public DistributionVo analysisAll(Long sd, Long ed) {
        //开始时间
        String start = DateUtil.formatDateTime(new Date(sd));
        //截止时间
        String end = DateUtil.formatDateTime(new Date(ed));

        List<AnalysisTimeVo> ageDistribution = analysisByDayMapper.findAgeDistribution("ageDistribution");
        List<AnalysisTimeVo> genderDistribution = analysisByDayMapper.findAgeDistribution("genderDistribution");
        List<AnalysisTimeVo> industryDistribution = analysisByDayMapper.findAgeDistribution("industryDistribution");
        List<AnalysisTimeVo> localDistribution = analysisByDayMapper.findAgeDistribution("localDistribution");
        List<AnalysisTimeVo> localTotal = analysisByDayMapper.findAgeDistribution("localTotal");

        DistributionVo distributionVo = new DistributionVo();
        for (AnalysisTimeVo analysisTimeVo : ageDistribution) {
            List<AnalysisTimeVo> analysisTimeVoList = new ArrayList<>();
            analysisTimeVoList.add(analysisTimeVo);
            distributionVo.setAgeDistribution(analysisTimeVoList);
        }
        for (AnalysisTimeVo analysisTimeVo : genderDistribution) {
            List<AnalysisTimeVo> analysisTimeVoList = new ArrayList<>();
            analysisTimeVoList.add(analysisTimeVo);
            distributionVo.setAgeDistribution(analysisTimeVoList);
        }
        for (AnalysisTimeVo analysisTimeVo : industryDistribution) {
            List<AnalysisTimeVo> analysisTimeVoList = new ArrayList<>();
            analysisTimeVoList.add(analysisTimeVo);
            distributionVo.setAgeDistribution(analysisTimeVoList);
        }
        for (AnalysisTimeVo analysisTimeVo : localDistribution) {
            List<AnalysisTimeVo> analysisTimeVoList = new ArrayList<>();
            analysisTimeVoList.add(analysisTimeVo);
            distributionVo.setAgeDistribution(analysisTimeVoList);
        }
        for (AnalysisTimeVo analysisTimeVo : localTotal) {
            List<AnalysisTimeVo> analysisTimeVoList = new ArrayList<>();
            analysisTimeVoList.add(analysisTimeVo);
            distributionVo.setAgeDistribution(analysisTimeVoList);
        }
        return distributionVo;
    }

    //实战: 新增,活跃用户,次日留存率
    @Override
    public YearsVo findSummaryByTime(Integer type, Long sd, Long ed) {
    //接收参数
        //开始时间
        String start = DateUtil.formatDateTime(new Date(sd));
        //截止时间
        String end = DateUtil.formatDateTime(new Date(ed));
        String lastYearSd = DateUtil.offsetDay(new Date(sd), -365).toDateStr();
        String lastYearEd = DateUtil.offsetDay(new Date(ed), -365).toDateStr();

        QueryWrapper<AnalysisByDay> queryWrapper1 = new QueryWrapper<>();
        QueryWrapper<AnalysisByDay> queryWrapper2 = new QueryWrapper<>();

        List<AnalysisByDay> recordDate1 = analysisByDayMapper.selectList(queryWrapper1.between("record_date", start, end));
        List<AnalysisByDay> recordDate2 = analysisByDayMapper.selectList(queryWrapper2.between("record_date", lastYearSd, lastYearEd));

        YearsVo yearsVo = new YearsVo();
        List<AnalysisTimeVo> thisYearList = new ArrayList<>();
        List<AnalysisTimeVo> lastYearList = new ArrayList<>();
        //3.根据查询种类返回对应的数值 : 101 新增 /102 活跃用户 /103 次日留存率
        if(CollectionUtil.isNotEmpty(recordDate1)) {
            //3-1.把今年的数据存到今年集合
            for (AnalysisByDay analysisByDay : recordDate1) {
                String title = DateUtil.formatDateTime(analysisByDay.getRecordDate());
                AnalysisTimeVo analysisTimeVo = new AnalysisTimeVo();
                analysisTimeVo.setTitle(title);

                if (type == 101) {//101 新增
                    analysisTimeVo.setAmount(analysisByDay.getNumRegistered());
                    thisYearList.add(analysisTimeVo);
                } else if (type == 102) {//102 活跃用户
                    analysisTimeVo.setAmount(analysisByDay.getNumActive());
                    thisYearList.add(analysisTimeVo);
                } else if (type == 103) {//103 次日留存率
                    analysisTimeVo.setAmount(analysisByDay.getNumRetention1d());
                    thisYearList.add(analysisTimeVo);
                }
            }
        }
        if (CollUtil.isNotEmpty(recordDate2)) {
            //3-1.把去年的数据存到去年集合
            for (AnalysisByDay analysisByDay : recordDate2) {
                //3-0.封装日期数据title
                String title = DateUtil.formatDateTime(analysisByDay.getRecordDate());
                AnalysisTimeVo analysisTimeVo = new AnalysisTimeVo();
                analysisTimeVo.setTitle(title);

                if(type == 101){//101 新增
                    analysisTimeVo.setAmount(analysisByDay.getNumRegistered());
                    lastYearList.add(analysisTimeVo);
                }else if(type == 102 ){//102 活跃用户
                    analysisTimeVo.setAmount(analysisByDay.getNumActive());
                    lastYearList.add(analysisTimeVo);
                }else if(type == 103 ){//103 次日留存率
                    analysisTimeVo.setAmount(analysisByDay.getNumRetention1d());
                    lastYearList.add(analysisTimeVo);
                }
            }
        }
            yearsVo.setThisYear(thisYearList);
            yearsVo.setLastYear(lastYearList);
            return yearsVo;
    }


    @Override
    public void saveOrUpdate() {
        //0.注入日期字符串
        String today = DateUtil.offsetDay(new Date(), 0).toDateStr();
        String yesterday = DateUtil.offsetDay(new Date(), -1).toDateStr();

        //1.调用logmapper查询各个数据
        int numRegister = logMapper.findCountByType(today, "0102");
        int numLogin = logMapper.findCountByType(today, "0101");
        int numActive = logMapper.findActiveCount(today);
        int numRetention1Day = logMapper.findRetention1Day(today, yesterday);

        //2.查询数据库中有无当日数据
        QueryWrapper<AnalysisByDay> qw = new QueryWrapper<>();
        qw.eq("record_date",today);

        AnalysisByDay analysisByDay = analysisByDayMapper.selectOne(qw);

        if (analysisByDay == null) {
            //2.1 若无则保存
            analysisByDay = new AnalysisByDay();

            analysisByDay.setRecordDate(new Date());
            analysisByDay.setNumRegistered(numRegister);
            analysisByDay.setNumActive(numActive);
            analysisByDay.setNumLogin(numLogin);
            analysisByDay.setNumRetention1d(numRetention1Day);

            // 保存
            analysisByDayMapper.insert(analysisByDay);
        }else{
            //2.2 若有则更新
            analysisByDay.setNumRegistered(numRegister);
            analysisByDay.setNumActive(numActive);
            analysisByDay.setNumLogin(numLogin);
            analysisByDay.setNumRetention1d(numRetention1Day);

            //更新
            analysisByDayMapper.updateById(analysisByDay);
        }
    }

    @Override
    public AnalysisSummaryVo findSummary() {
        //0.准备时间的字符串
        String today = DateUtil.offsetDay(new Date(), 0).toDateStr();
        String yesterday = DateUtil.offsetDay(new Date(), -1).toDateStr();
        String passWeek = DateUtil.offsetDay(new Date(), -7).toDateStr();
        String passMonth = DateUtil.offsetDay(new Date(), -30).toDateStr();

        //1.创建AnalysisSummaryVo对象
        AnalysisSummaryVo analysisSummaryVo = new AnalysisSummaryVo();

        //2.封装对象(9个数据)
        //2.1 调用mapper的自定义查询累计用户数
        Long userSum = analysisByDayMapper.findUserSum();

        //2.2 调用mapper的自定义查询过去30天活跃人数
        Long activePassMonth = analysisByDayMapper.findCountWithinPeriod(passMonth, yesterday);

        //2.3 调用mapper的自定义查询过去7天活跃人数
        Long activePassWeek = analysisByDayMapper.findCountWithinPeriod(passWeek, yesterday);

        //2.4 查询今日分析统计对象
        QueryWrapper<AnalysisByDay> qw = new QueryWrapper<>();
        qw.eq("record_date",today);
        AnalysisByDay todaySummary = analysisByDayMapper.selectOne(qw);
        System.out.println(todaySummary);
        //2.5 查询昨日分析统计对象
        qw = new QueryWrapper<>();
        qw.eq("record_date",yesterday);
        AnalysisByDay yesterdaySummary = analysisByDayMapper.selectOne(qw);
        System.out.println(yesterdaySummary);
        //2.6 封装9个数据
        analysisSummaryVo.setCumulativeUsers(userSum);
        analysisSummaryVo.setActivePassMonth(activePassMonth);
        analysisSummaryVo.setActivePassWeek(activePassWeek);
        analysisSummaryVo.setNewUsersToday(todaySummary.getNumRegistered().longValue());
        analysisSummaryVo.setNewUsersTodayRate(ComputeUtil.computeRate(todaySummary.getNumRegistered(),yesterdaySummary.getNumRegistered()));
        analysisSummaryVo.setLoginTimesToday(todaySummary.getNumLogin().longValue());
        analysisSummaryVo.setLoginTimesTodayRate(ComputeUtil.computeRate(todaySummary.getNumLogin(),yesterdaySummary.getNumLogin()));
        analysisSummaryVo.setActiveUsersToday(todaySummary.getNumActive().longValue());
        analysisSummaryVo.setActiveUsersTodayRate(ComputeUtil.computeRate(todaySummary.getNumActive(),yesterdaySummary.getNumActive()));

        //3.返回
        return analysisSummaryVo;
    }
}
